S07-03 数据可视化-SVG
[TOC]
邂逅 SVG
什么是 SVG?维基百科介绍:
SVG 全称为(Scalable Vector Graphics),即可缩放矢量图形。(矢量定义:既有大小又有方向的量。在物理学中称作矢量,如一个带箭头线段:长度表示大小,箭头表示方向;在数学中称作向量。在计算机中,矢量图可无限放大而不变形)
SVG 是一种基于 XML 格式的矢量图,主要用于定义二维图形,支持交互和动画。
SVG 规范是万维网联盟(W3C) 自 1998 年以来开发的标准。
SVG 图像可在不损失质量的情况下按比例缩放,并支持压缩。
基于 XML 的 SVG 可轻松的用文本编辑器或矢量图形编辑器创建和编辑,并可以直接在浏览器显示。
SVG 对浏览器的兼容性:
SVG 历史
SVG1.x 版本
SVG 是 W3C SVG 工作组于 1998 年开始开发 ,而 SVG 1.0 于 2001 年 9 月 4 日成为 W3C 推荐的标准。
SVG 1.1 于 2003 年 1 月 14 日成为 W3C 推荐的标准。 该版本增加了模块化规范的内容。除此之外,1.1 和 1.0 几乎没有区别。
SVG Tiny 1.2 于 2008 年 12 月 22 日成为 W3C 推荐标准,主要是为性能低的小设备生成图形,但是后来被 SVG 2 所弃用了。
SVG 1.1 第二版 于 2011 年 8 月 16 日发布,这次只是更新了勘误表和说明,并没有增加新功能 。
SVG 2.0 版本(推荐)
SVG 2.0 于 2016 年 9 月 15 日成为 W3C 候选推荐标准,最新草案于 2020 年 5 月 26 日发布。
SVG2.x Change From SVG1.x ( https://www.w3.org/TR/SVG/changes.html ),比如:
Removed the baseProfile and version attributes from the ‘svg’ element.
Added the ability to use 'auto' for the widthand heightattributes on ‘image’.
Removed the ‘xlink:type’, ‘xlink:role’, ‘xlink:arcrole’, ‘xlink:show’ and ‘xlink:actuate’ attributes.
Deprecated the ‘xlink:href’ attribute in favor of using ‘href’ without a namespace.
SVG 优点
扩展好:矢量图像在浏览器中放大缩小不会失真,可被许多设备和浏览器中使用。而光栅图像(PNG 、JPG)放大缩小会失真。
矢量图像是基于矢量的点、线、形状和数学公式来构建的图形,该图形是没有像素的,放大缩小是不会失真的。
光栅图像是由像素点构建的图像——微小的彩色方块,大量像素点可以形成高清图像,比如照片。图像像素越多,质量越高。
灵活:SVG 是 W3C 开发的标准,可结合其它的语言和技术一起使用,包括 CSS、JavaScript、 HTML 和 SMIL 。SVG 图像可以
直接使用 JS 和 CSS 进行操作,使用时非常方便和灵活,因为 SVG 也是可集成到 DOM 中的。
可以动画:SVG 图像可以使用 JS 、 CSS 和 SMIL 进行动画处理。对于 Web 开发人员来说非常的友好。
轻量级:与其它格式相比,SVG 图像的尺寸非常小。根据图像的不同,PNG 图像质量可能是 SVG 图像的 50 倍。
可打印:SVG 图像可以以任何分辨率打印,而不会损失图像质量。
利于 SEO:SVG 图像被搜索引擎索引。因此,SVG 图像非常适合 SEO(搜索引擎优化)目的。
可压缩:与其它图像格式一样,SVG 文件支持压缩。
易于编辑:只需一个文本编辑器就可以创建 SVG 图像。设计师通常会使用 Adobe Illustrator (AI)等矢量图形工具创建和编辑。
SVG 缺点
不适和高清图片制作
SVG 格式非常适合用于徽标和图标(ICON)等 2D 图形,但不适用于高清图片,不适合进行像素级操作。
SVG 的图像无法显示与标准图像格式一样多的细节,因为它们是使用点和路径而不是像素来渲染的。
SVG 图像变得复杂时,加载会比较慢
不完全扩平台
- 尽管 SVG 自 1998 年以来就已经存在,并得到了大多数现代浏览器(桌面和移动设备)的支持,但它不适用于 IE8 及更低版本的旧版浏览器。根据 caniuse 的数据,大约还有 5% 的用户在使用不支持 SVG 的浏览器。
SVG 应用场景
SVG 应用场景有哪些? 下面是一些保证 SVG 优于其他图像格式的应用场景:
SVG 非常适合显示矢量徽标(Logo)、图标(ICON)和其他几何设计。
SVG 适合应用在需适配多种尺寸的屏幕上展示,因为 SVG 的扩展性更好。
当需要创建简单的动画时,SVG 是一种理想的格式。
SVG 可以与 JS 交互来制作线条动画、过渡和其他复杂的动画。
SVG 可以与 CSS 动画交互,也可以使用自己内置的 SMIL 动画。
SVG 也非常适合制作各种图表(条形图、折线图、饼图、散点图等等),以及大屏可视化页面开发。
SVG 和 Canvas 的区别
可扩展性:
SVG 是基于矢量的点、线、形状和数学公式来构建的图形,该图形是没有像素的,放大缩小不会失真。
Canvas 是由一个个像素点构成的图形,放大会使图形变得颗粒状和像素化(模糊)。
SVG 可以在任何分辨率下以高质量的打印。Canvas 不适合在任意分辨率下打印。
渲染能力:
当 SVG 很复杂时,它的渲染就会变得很慢,因为在很大程度上去使用 DOM 时,渲染会变得很慢。
Canvas 提供了高性能的渲染和更快的图形处理能力,例如:适合制作 H5 小游戏。
当图像中具有大量元素时,SVG 文件的大小会增长得更快(导致 DOM 变得复杂),而 Canvas 并不会增加太多。
灵活度:
SVG 可以通过 JavaScript 和 CSS 进行修改,用 SVG 来创建动画和制作特效非常方便。
Canvas 只能通过 JavaScript 进行修改,创建动画得一帧帧重绘。
使用场景:
Canvas 主要用于游戏开发、绘制图形、复杂照片的合成,以及对图片进行像素级别的操作,如:取色器、复古照片。
SVG 非常适合显示矢量徽标(Logo)、图标(ICON)和其他几何设计。
初体验 SVG
如何绘制一个 SVG 矢量图? 绘制 SVG 矢量图常用有 4 种方式:
方式一:在一个单独的 svg 文件中绘制,svg 文件可直接在浏览器预览或嵌入到 HTML 中使用(推荐)
方式二:直接在 HTML 文件中使用 svg 元素来绘制(推荐)
方式三:直接使用 JavaScript 代码来生成 svg 矢量图。
方式四:使用 AI(Adobe IIIustractor)矢量绘图工具来绘制矢量图,并导出为 svg 文件(推荐)
SVG 初体验
第一步:新建一个 svg 文件,在文件第一行编写 XML 文件声明
第二步:编写 一个
<svg>
元素,并给该元素添加如下属性:version: 指定使用 svg 的版本,值为 1.0 和 1.1,并没有 2.0。baseProfile:SVG 2 之前,version 和 baseProfile 属性用来验证和识别 SVG 版本。而 SVG2 后不推荐使用这两个属性了。width / height :指定 svg 画布(视口)的宽和高,默认值分别为 300 和 150,默认使用 px 单位。
xmlns:给 svg 元素帮定一个命名空间(http://www.w3.org/2000/svg)意味着这个
<svg>
标签和它的子元素都属于该命名空间下。
第三步:在
<svg>
元素中添加 图形(比如:<rect>
) 元素第四步:在浏览器直接预览 或 嵌入到 HTML 中预览(嵌入 HTML 有 6 种方案)
XML 和 DT D 声明
由于 SVG 是一个 XML 文件格式。在编写 XML 文档时,通常是推荐编写 XML 声明。因为在 XML 1.0 中,XML 声明是可选的,推荐写但不是强制性。
然而,在 XML 1.1 中,声明是强制性的,如果没有声明,则自动暗示该文档是 XML 1.0 文档。所以这里建议大家在编写 SVG 文件时也编写一个
XML 声明。
SVG 的 XML 声明格式:<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
version 指定版本(必填)
encoding 指定 XML 文档的编码(可选,默认是 UTF-8)
standalone:指定当前 XML 文档是否依赖于外部标记声明(可选,使用该属性时,需和 DTD 声明一起用才有意义)。
默认为 no:代表依赖外部标记声明
yes:代表依赖内部默认的标记声明
SVG 的文档类型声明(DTD),让解析器验证 XML 文件是否符合该规范,与 HTML5 文件的 DTD 声明类似。
XML 中内部 DTD 声明(可选)
XML 中外部 DTD 声明(可选)
html<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
SVG 文档结构
SVG1.1 文档结构:https://www.w3.org/TR/SVG11/struct.html
第一行:包含一个 XML 声明。由于 SVG 文件是一个 XML 格式的,它应包含一个 XML 声明。
第二行:定义文档类型声明 (DTD),这里依赖外部的 SVG1.1 文档类型,让解析器验证 XML 文件是否符合该规范。
<!DOCTYPE svg PUBLIC “-//W3C//DTD SVG 1.1//EN” "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
SVG2.0 文档结构:https://www.w3.org/TR/SVG2/struct.html#Namespace
- SVG2 version 和 baseProfile 属性已删除,也不推荐写文档类型声明(DTD)。其中
<desc>
元素是用来描述该文件的。
JS 创建 SVG
使用 JS 脚本来创建 SVG 时,创建的元素都是需要添加命名空间的。
比如:创建
<svg>
或者<rect>
元素都需要添加命名空间(http://www.w3.org/2000/svg)对于元素上的属性如果不带前缀的,命名空间赋值为 null。
因为在 XML1.1 命名空间规范中建议,不带前缀的属性(带前缀 xlink:href)命名空间的名称是没有值的,这时命名空间的值必须
使用 null 值。
创建 SVG 常用的 DOM2 API:
createElementNS(ns,elname):创建 SVG 元素
setAttributeNS(ns,attrname,value):给 SVG 元素添加属性
getAttributeNS(ns,attrname):获取 SVG 元素上的属性
hasAttributeNS(ns, attrname): 判断 SVG 元素上是否存在某个属性
removeAttributeNS(ns,attname):删除 SVG 元素上的某个属性
更多的 API:https://developer.mozilla.org/zh-CN/docs/Web/SVG/Namespaces\_Crash\_Course
HTML 引入 SVG
方式一:img 元素
- 作为一张图片使用,不支持交互,只兼容 ie9 以上
方式二:CSS 背景
- 作为一张背景图片使用,不支持交互
方式三:直接在 HTML 文件引用源文件
- 作为 HTML 的 DOM 元素,支持交互,只兼容 ie9 以上
方式四:object 元素(了解)。
- 支持交互式 svg,能拿到 object 的引用,为 SVG 设置动画、更改其样式表等
方式五:iframe 元素(了解) 。
- 支持交互式 svg,能拿到 iframe 的引用,为 SVG 设置动画、更改其样式表等
方式六:embed 元素(了解) 。
- 支持交互式 svg,能拿到 embed 的引用,为 SVG 设置动画、更改其样式表等,对旧版浏览器有更好的支持。
SVG Grid 和 坐标系
SVG 使用的坐标系统(网格系统)和 Canvas 的差不多。坐标系是 以左上角为 (0,0) 坐标原点,坐标以像素为单位,x 轴正方向是向右,y 轴正方向是向下。
SVG Grid(坐标系)
<svg>
元素默认宽为 300px, 高为 150px。如右图所示,<svg>
元素默认被网格所覆盖。通常来说网格中的一个单元相当于 svg 元素中的一像素。
基本上在 SVG 文档中的 1 个像素对应输出设备(比如显示屏)上的 1 个像素(除非缩放)。
<svg>
元素和其它元素一样也是有一个坐标空间的,其原点位于元素的左上角,被称为初始视口坐标系<svg>
的 transform 属性可以用来移动、旋转、缩放 SVG 中的某个元素,如<svg>
中某个元素用了变形,该元素内部会建立一个新的坐标系统,该元素默认后续所有变化都是基于新创建的坐标系统。
SVG 坐标系单位
SVG 坐标系统,在没有明确指定单位时,默认以像素为单位。
比如:<rect x="0" y="0" width="100" height="100" />
- 定义一个矩形,即从左上角开始,向右延展 100px,向下延展 100px,形成一个 100*100 大的矩形。
当然我们也可以手动指明坐标系的单位,比如:
视口-viewport
视口(viewport)
视口是 SVG 可见的区域(也可以说是 SVG 画布大小)。可以将视口视为可看到特定场景的窗口。
可以使用
<svg>
元素的 width 和 height 属性指定视口的大小。一旦设置了最外层 SVG 元素的宽度和高度,浏览器就会建立初始视口坐标系和初始用户坐标系。
视口坐标系
视口坐标系是在视口上建立的坐标系,原点在视口左上角的点(0, 0),x 轴正向向右,y 轴正向下。
初始视口坐标系中的一个单位等于视口中的一个像素,该坐标系类似于 HTML 元素的坐标系。
用户坐标系( 也称为当前坐标系或正在使用的用户空间,后面绘图都是参照该坐标系 )
用户坐标系是建立在 SVG 视口上的坐标系。该坐标系最初与视口坐标系相同——它的原点位于视口的左上角。
使用 viewBox 属性,可以修改初始用户坐标系,使其不再与视口坐标系相同。
为什么要有两个坐标系?
- 因为 SVG 是矢量图,支持任意缩放。在用户坐标系统绘制的图形,最终会参照视口坐标系来进行等比例缩放。
视图框-viewBox
视图框(viewBox)
viewport 是 SVG 画布的大小,而 viewBox 是用来定义用户坐标系中的位置和尺寸 (该区域通常会被缩放填充视口)。
viewBox 也可理解为是用来指定用户坐标系大小。因为 SVG 的图形都是绘制到该区域中。用户坐标系可以比视口坐标系更小或更大,也可以在
视口内完全或部分可见。
一旦创建了视口坐标系(
<svg>
使用 width 和 height),浏览器就会创建一个与其相同的默认用户坐标系。我们可以使用 viewBox 属性指定用户坐标系的大小。
如果用户坐标系与视口坐标系具有相同的高宽比,它将 viewBox 区域拉伸以填充视口区域。
如果用户坐标系和视口坐标系没有相同的宽高比,可用 preserveAspectRatio 属性来指定整个用户坐标系统是否在视口内可见。
viewBox 语法
viewBox =
<min-x>
<min-y>
<width>
<height>
,比如:viewBox =' 0 0 100 100'
<min-x>
和<min-y>
确定视图框的左上角坐标(不是修改用户坐标系的原点,绘图还是从原来的 0, 0 开始)<width>
<height>
确定该视图框的宽度和高度。宽度和高度不必与父
<svg>
元素上设置的宽度和高度相同。宽度和高度负值无效,为 0 是禁用元素的显示。
视图框-viewBox-相同的宽高比
看一个 viewport 和 viewBox 有相同的宽高比的例子:
在 viewBox 属性上设置视图框为视口大小的一半。
暂时不改变这个视图框左上角,将
<min-x>
将<min-y>
设置为零。视图框的宽度和高度将是视口宽度和高度的一半。
那么,viewbox="0 0 100 100" 具体做什么的呢?
指定画布可显示的区域,用户坐标系从 (0, 0) 的左上点到 (100, 100) 的点,默认单位是 px。
然后将 SVG 图形绘制到该 viewBox 区域。
viewBox 区域等比例被放大(放大不会失真)以填充整个视口。
用户坐标系映射到视口坐标系,因此——在这种情况下——1 个用户单位等于 4 个视口单位。
在 SVG 画布上绘制的任何内容都将相对于该用户坐标系进行绘制 。
视图框-viewBox-不同的宽高比
在 400*400 的视口中,viewbox="0 0 200 100" 具体做什么的呢?
保留视图框 viewBox 的宽高比,但视图框 viewBox 不会拉伸以覆盖整个视口区域。
视图框 viewBox 在视口内垂直和水平居中 。
想改变视口内的视框位置怎么办?
给
<svg>
添加 preserveAspectRatio 属性,该属性允许强制统一缩放视图框 viewBoxpreserveAspectRatio= "none", 强制拉伸图形以填充整个视口。
preserveAspectRatio= “xMinYMin”, 图形在视口的最小 x 和 y 轴上显示
.....
绘制-矩形 ( rect )
SVG 的基本形状
在 SVG 画布中,如果要想插入一个形状,可以在文档中创建一个对应的元素。
不同的元素对应着不同的形状,并且可以使用不同的属性来定义图形的大小和位置。
SVG 所支持的基本形状有:矩形、圆形、椭圆、线条、折线、多边形、路径。
下面用 SVG 来绘制一个矩形(rect)
<rect>
元素会在屏幕上绘制<rect>
元素有 6 个基本属性可以控制它在屏幕上的位置和形状。
<rect>
元素 6 个基本属性
x :矩形左上角的 x 轴位置
y :矩形左上角的 y 轴位置
width :矩形的宽度
height :矩形的高度
rx :圆角的 x 轴方位的半径
ry :圆角的 y 轴方位的半径 。
绘制-圆形 ( circle )
下面用 SVG 来绘制一个圆形(circle)
<circle>
元素会在屏幕上绘制一个圆形。<circle>
元素有 3 个基本属性用来设置圆形。
<circle>
元素 3 个基本属性
r :圆的半径
cx :圆心的 x 轴位置
cy :圆心的 y 轴位置
绘制-椭圆 ( ellipse )
下面用 SVG 来绘制一个椭圆(ellipse)
<ellipse>
元素是<circle>
元素更通用的形式,它可以分别缩放圆的 x 半径和 y 半径 。x 半径和 y 半径 ,数学家通常称之为长轴半径和短轴半径
<ellipse>
元素有 4 个基本属性用来设置椭圆。
<ellipse>
元素 4 个基本属性
rx :椭圆的 x 轴半径
ry :椭圆的 y 轴半径
cx :椭圆中心的 x 轴位置
cy :椭圆中心的 y 轴位置
绘制-线条( line )
下面用 SVG 来绘制一条直线(line)
<line>
元素是绘制直线。它取两个点的位置作为属性,指定这条线的起点和终点位置。需描边才能显示,不支持填充和 Canvas 线条一样。
<line>
元素有 4 个基本属性用来设置线条。
<line>
元素 4 个基本属性
x1 :起点的 x 轴位置
y1 :起点的 y 轴位置
x2 :终点的 x 轴位置
y2 :终点的 y 轴位置
绘制-折线( polyline )
下面用 SVG 来绘制一条直线(polyline)
<polyline>
元素是一组连接在一起的直线。因为它可以有很多的点,折线的的所有点位置都放在一个 points 属性。默认会填充黑色
<polyline>
元素有 1 个基本属性用来设置折线所有点位置。
<polyline>
元素 1 个基本属性
points : 点集数列。每个数字用空白、逗号、终止命令符或者换行符分隔开。
每个点必须包含 2 个数字,一个是 x 坐标,一个是 y 坐标。
所以点列表 (0,0), (1,1) 和 (2,2) 可以写成这样:“0 0, 1 1, 2 2”。
- 支持格式: “0 0, 1 1, 2 2”或 “0 ,0 , 1, 1, 2, 2”或 “0 0 1 1 2 2”
绘制-多边型(polygon)
下面用 SVG 来绘制多边形(polygon)
<polygon>
元素是和折线很像,它们都是由连接一组点集的直线构成。不同的是,<polygon>
的路径在最后一个点处自动回到第一个点。需要注意的是,矩形也是一种多边形,也可以用多边形创建一个矩形。默认会填充黑色
<polygon>
元素有 1 个基本属性用来设置多边形线所有点位置。
<polygon>
元素 1 个基本属性
points :点集数列。每个数字用空白符、逗号、终止命令或者换行符分隔开。
每个点必须包含 2 个数字,一个是 x 坐标,一个是 y 坐标。
所以点列表 (0,0), (1,1) 和 (2,2) 推荐写成这样:“0 0, 1 1, 2 2”。
路径绘制完后闭合图形,所以最终的直线将从位置 (2,2) 连接到位置 (0,0)。
绘制-路径(path)
下面用 SVG 来绘制路径(path)
<path>
元素可能是 SVG 中最常见的形状。你可以用<path>
元素绘制矩形(直角矩形或圆角矩形)、圆形、椭圆、折线形、多边形,以及一些其他的形状,例如贝塞尔曲线、2 次曲线等曲线。默认会填充黑色,默认路径不会闭合
<path>
元素有 1 个基本属性用来设置路径点的位置。
<path>
元素 1 个基本属性
d :一个点集数列,以及其它关于如何绘制路径的信息,必须 M 命令开头。
所以点列表 (0,0), (1,1) 和 (2,2) 推荐写成这样:“M 0 0, 1 1, 2 2”。
支持格式: “M 0 0, 1 1, 2 2”或 “M0 0, 1 1, 2 2” 或 “M 0 ,0 , 1, 1, 2, 2”或 “M 0 0 1 1 2 2”
SVG 路径 和 命令
SVG 路径(path) 和 命名
<path>
元素是 SVG 基本形状中最强大的一个。 你可以用它创建线条,曲线,弧形等等。<path>
元素的形状是通过属性 d 定义的,属性 d 的值是一个 “命令 + 参数 ”的序列。每一个命令都用一个关键字母来表示,比如,字母“M”表示的是“Move to”命令,当解析器读到这个命令时,它就知道你是打算移动到某个点。跟在命令字母后面的,是你需要移动到的那个点的 x 和 y 轴坐标。比如移动到 (10,10) 这个点的命令,应该写成“M10 10”命令。这一段字符结束后,解析器就会去读下一段命令。每一个命令都有两种表示方式,一种是用大写字母,表示采用绝对定位。另一种是用小写字母,表示采用相对定位(例如:从上一个点开始,向上移动 10px,向左移动 7px)。
属性 d 采用的是用户坐标系统,不需标明单位。
d 属性值支持的命令
直线命令
M / m:Move To
L / l :Line To
Z / z:Close Path
H / h:horizontal
V / v:vertical
曲线命令
- C :三次贝塞尔曲线
- S:简写三次贝塞尔曲线
- Q:二次贝塞尔曲线
- T:简写二次贝塞尔曲线
绘制-图片
在 SVG 中绘制一张图片
- 在
<image>
元素的 href 属性引入图片 URL
注意事项
image 元素没设置 x , y 值,它们自动被设置为 0。
image 元素没设置 height 、width 时,默认为图片大小。
width 、height 等于 0,将不会呈现这个图像。
需在 href 属性上引用外部的图像,不是 src 属性。
href 属性兼容性: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/href#browser\_compatibility
绘制-文字
下面我们来看一下如何在 SVG 画布中绘制文字。
<text>
元素是用来在 SVG 画布中绘制文字用的。
<text>
元素的基本属性
x 和 y 属性决定了文本在用户坐标系中显示的位置。
text-anchor 文本流方向属性,可以有 start、middle、end 或 inherit 值,默认值 start
dominant-baseline 基线对齐属性 : 有 auto 、middle 或 hanging 值, 默认值:auto
<text>
元素的字体属性
文本的一个至关重要的部分是它显示的字体。SVG 提供了一些属性,类似于 CSS 。下列的属性可以被设置为一个 SVG 属性或一个 CSS 属性:
- font-family、font-style、font-weight、font-variant、font-stretch、font-size、font-size-adjust、kerning、letter-spacing、word-spacing 和 text-decoration。
其它文本相关的元素:
<tspan>
元素用来标记大块文本的子部分,它必须是一个 text 元素或别的 tspan 元素的子元素。x 和 y 属性决定了文本在视口坐标系中显示的位置。
alignment-baseline 基线对齐属性:auto 、baseline、middle、hanging、top、bottom ... ,默认是 auto
元素的组合(g)
元素的组合
<g>
元素是用来组合元素的容器。添加到 g 元素上的变换会应用到其所有的子元素上。
添加到 g 元素的属性大部分会被其所有的子元素继承。
g 元素也可以用来定义复杂的对象,之后可以通过
<use>
元素来引用它们
<g>
元素的属性(该元素只包含全局属性)
核心属性:id
样式属性:class 、style
Presentation Attributes(也可说是 CSS 属性,这些属性可写在 CSS 中,也可作为元素的属性用):
cursor, display, fill, fill-opacity, opacity,…
stroke, stroke-dasharray, stroke-dashoffset, stroke-linecap, stroke-linejoin
更多表示属性:https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation
事件属性:onchange, onclick, ondblclick, ondrag…
动画属性:transform
更多:https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g
图形元素的复用(defs)
SVG 是允许我们定义一些可复用元素的。
即把可复用的元素定义在
<defs>
元素里面,然后通过<use>
元素来引用和显示。这样可以增加 SVG 内容的易读性、复用性和利于无障碍开发。
<defs>
元素,定义可复用元素。
例如:定义基本图形、组合图形、渐变、滤镜、样式等等。
在
<defs>
元素中定义的图形元素是不会直接显示的。可在视口任意地方用
<use>
来呈现在 defs 中定义的元素。<defs>
元素没有专有属性,使用时通常也不需添加任何属性。
<defs>
定义的元素的坐标系参照哪个?用户坐标系
引入元素(use)
<use>
元素从 SVG 文档中获取节点,并将获取到的节点复制到指定的地方。
<use>
等同于深度克隆 DOM 节点,克隆到 use 元素所在的位置。克隆的节点是不可见的,当给
<use>
元素应用 CSS 样式时须小心。因为克隆的 DOM 不能保证都会继承<use>
元素上的 CSS
属性,但是 CSS 可继承的属性是会继承的。
<use>
元素的属性
href: 需要复制元素/片段的 URL 或 ID(支持跨 SVG 引用)。默认值:无
~~xlink:href:(SVG2.0 已弃用)~~需要复制的元素/片段的 URL 或 ID 。默认值:无
x / y :元素的 x / y 坐标(相对复制元素的位置)。 默认值:0
width / height :元素的宽和高(在引入 svg 或 symbol 元素才起作用)。 默认值:0
图形元素复用(symbols)
<symbol>
元素和<defs>
元素类似,也是用于定义可复用元素,然后通过<use>
元素来引用显示。
在
<symbol>
元素中定义的图形元素默认也是不会显示在界面上。<symbol>
元素常见的应用场景是用来定义各种小图标,比如:icon、logo、徽章等
<symbol>
元素的属性
viewBox:定义当前
<symbol>
的视图框。x / y :symbol 元素的 x / y 坐标。 ;默认值:0
width / height:symbol 元素的宽度。 默认值:0
<symbol>
和<defs>
的区别
<defs>
元素没有专有属性,而<symbol>
元素提供了更多的属性- 比如: viewBox、 preserveAspectRatio 、x、y、width、height 等。
<symbol>
元素有自己用户坐标系,可以用于制作 SVG 精灵图。<symbol>
元素定义的图形增加了结构和语义性,提高文档的可访问性。
SVG ICON 文件-合并成 SVG 精灵图:https://www.zhangxinxu.com/sp/svgo
填充和描边
如果想要给 SVG 中的元素上色,一般有两种方案可以实现:
第一种:直接使用元素的属性,比如:填充(fill)属性、描边(stroke)属性等。
第二种:直接编写 CSS 样式,因为 SVG 也是 HTML 中的元素,也支持用 CSS 的方式来编写样式。
第一种:直接使用元素的属性(填充和描边)
在 SVG 中,绝大多数元素的上色都可通过 fill 和 stroke 两个属性来搞定。
fill 属性:设置对象填充颜色。支持:颜色名、十六进制值、rgb、 rgba 。
stroke 属性:设置绘制对象的边框颜色。支持:颜色名、十六进制值、rgb、 rgba 。
第一种:填充属性(fill)
fill 填充属性,专门用来给 SVG 中的元素填充颜色。
- fill =“color ”。支持:颜色名、十六进制值、rgb、 rgba 、 currentColor (继承自身或父亲字体 color)。
如下图给矩形填充颜色:fill=“pink”
控制填充色的不透明
- fill-opacity = ”number ”, 该属性专门用来控制填充色的不透明,值为 0 到 1。
第一种:描边属性(stroke)
stroke 描边属性
stroke = “color ”: 指定元素边框填充颜色。
stroke-opacity = “number”:控制元素边框填充颜色的透明度。
stroke-width = “number”:指定边框的宽度。注意,边框是以路径为中心线绘制的。
stroke-linecap =“butt | square | round”:控制边框端点的样式。
stroke-linejoin = “miter | round | bevel”:控制两条线段连接处样式
stroke-dasharray =“number [, number , ….]”: 将虚线类型应用在边框上。
该值必须是用逗号分割的数字组成的数列,空格会被忽略。比如 3,5 :
第一个表示填色区域长度为 3
第二个表示非填色区域长度为 5
stroke-dashoffset:指定在 dasharray 模式下路径的偏移量。
- 值为 number 类型,除了可以正值,也可以取负值。
第二种:CSS 样式
直接编写 CSS 样式实现填充和描边
除了定义元素的属性外,你也可以通过 CSS 来实现填充和描边(CSS 样式可写在 defs 中,也可写在 HTML 头部或外部等)。
语法和 HTML 里使用 CSS 一样,需要注意的是:需要把 background-color、border 改成 fill 和 stroke
不是所有的属性都能用 CSS 来设置,上色和填充的部分是可以用 CSS 来设置。
- 比如,fill,stroke,stroke-dasharray 等可以用 CSS 设置;比如,路径的命令则不能用 CSS 设置。
哪些属性可以使用 CSS 设置,哪些不能呢?
SVG 规范中将属性区分成 Presentation Attributes 和 Attributes 属性。
Presentation Attributes 属性( 支持 CSS 和元素用 ):https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation
Attributes 属性(只能在元素用): https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute
提示:这些属性是不需要去记的,用多了就记住了,在忘记时测试一下就知道了。
CSS 给 SVG 中的元素填充、描边和上色,支持如下 4 种编写方式:
方式一:内联(行内) CSS 样式,写在元素的 style 属性上
方式二:内嵌(内部) CSS 样式,写在
<defs>
中的<style>
标签中方式三:内嵌(内部) CSS 样式,写在
<head>
中的<style>
标签中方式四:外部 CSS 样式文件,写在 .css 文件中
CSS 样式优先级别:内联的 style > defs 中的 style > 外部 / head 内部 > 属性 fill
线性渐变
SVG 除了可以简单的填充和描边,还支持在填充和描边上应用渐变色。渐变有两种类型:线性渐变 和 径向渐变。
编写渐变时,必须给渐变内容指定一个 id 属性,use 引用需用到。
建议渐变内容定义在
<defs>
标签内部,渐变通常是可复用的。
线性渐变,是沿着直线改变颜色。下面看一下线性渐变的使用步骤:
第 1 步:在 SVG 文件的 defs 元素内部,创建一个
<linearGradient>
节点,并添加 id 属性。第 2 步:在
<linearGradient>
内编写几个<stop>
结点。给
<stop>
结点指定位置 offset 属性和 颜色 stop-color 属性,用来指定渐变在特定的位置上应用什么颜色- offset 和 stop-color 这两个属性值,也可以通过 CSS 来指定。
也可通过 stop-opacity 来设置某个位置的半透明度。
第 3 步:在一个元素的 fill 属性或 stroke 属性中通过 ID 来引用
<linearGradient>
节点。比如:属性 fill 属性设置为 url( #Gradient2 )即可。
第 4 步(可选):控制渐变方向,通过 ( x1, y1 ) 和 ( x2, y2 ) 两个点控制。
(0, 0) (0, 1)从上到下;(0, 0)(1, 0)从左到右。
当然也可以通过 gradientTransform 属性 设置渐变形变。比如: gradientTransform=“rotate(90)” 从上到下。
SVG 毛玻璃效果
在前端开发中,毛玻璃效果有几种方案来实现:
方案一:使用 CSS 的 backdrop-filter 或 filter 属性
**backdrop-filter:**可以给一个元素后面区域添加模糊效果。
适用于元素背后的所有元素。为了看到效果,必须使元素或其背景至少部分透明。
**filter:**直接将模糊或颜色偏移等模糊效果应用于指定的元素。
方案二:使用 SVG 的 filter 和 feGaussianBlur 元素(建议少用)
<filter>
:元素作为滤镜操作的容器,该元素定义的滤镜效果需要在 SVG 元素上的 filter 属性引用。- x , y, width, height 定义了在画布上应用此过滤器的矩形区域。x, y 默认值为 -10%(相对自身);width ,height 默认值为 120% (相对自身) 。
<feGaussianBlur>
:该滤镜专门对输入图像进行高斯模糊- stdDeviation 熟悉指定模糊的程度
<feOffset>
:该滤镜可以对输入图像指定它的偏移量。
形变- transform
transform 属性用来定义元素及其子元素的形变的列表。
此属性可以与任何一个 SVG 中的元素一起使用。如果使用了变形,会在该元素内部建立了一个新的坐标系统。
从 SVG2 开始,transform 它是一个 Presentation Attribute,意味着它可以用作 CSS 属性。
但是 transform 作为 CSS 属性和元素属性之间的语法会存在一些差异。
- 比如作为元素属性时:支持 2D 变换,不需单位,rotate 可指定旋转原点。
transform 属性支持的函数:
translate(x, y) 平移。
rotate(z) / rotate(z, cx,cy) :旋转。
scale(x, y) :缩放
skew(x, y) :倾斜。
matrix(a, b, c, d, e) : 2*3 的形变矩阵
注意:形变会不会修改坐标系? 会,形变元素内部会建立一个新的坐标系,后续的绘图或形变都会参照新的坐标系。
形变-平移
平移:把元素移动一段距离, 使用 transform 属性的 translate()函数来平移元素。
- 与 CSS 的 translate 相似但有区别,这里只支持 2D 变换,不需单位。
translate(x, y)函数
一个值时,设置 x 轴上的平移,而第二个值默认赋值为 0
二个值时,设置 x 轴和 y 轴上的平移
平移案例:将一个矩形由默认的(0,0)点,移到点 (30,40)。
注意:平移会不会修改坐标系? 会,元素内部会建立一个新的坐标系。
形变-旋转
旋转:把元素旋转指定的角度, 使用 transform 属性的 rotate(deg,cx, cy) 函数来旋转元素。
- 与 CSS 的 rotate 相似但有区别。区别是:支持 2D 变换,不需单位,可指定旋转原点。
rotate(deg, cx, cy) 函数
- 一个值时,设置 z 轴上的旋转的角度。
注意:
旋转会不会修改坐标系? 会,坐标轴也会跟着旋转了
如何指定旋转原点? 直接在 rotate 中指定 cx ,cy(相对于自身); 或者使用 CSS 样式写动画。
形变-缩放
缩放:改变元素尺寸,使用 transform 属性的 scale() 函数来缩放元素。
- 与 CSS 的 scale 相似但有区别,这只支持 2D 变换,不需单位。
scale(x, y)函数
二个值时:它需要两个数字,作为比率计算如何缩放。0.5 表示收缩到 50%。
一个值时:第二个数字被忽略了,它默认等于第一个值。
注意:
缩放会不会修改坐标系?会,坐标轴被缩放了。
如何指定缩放的原点? SVG 属性实现需要 平移坐标 和 移动图形了;或者 直接使用 CSS 来写动画
stroke 描边动画
stroke 是描边属性,专门给图形描边。如果想给各种描边添加动画效果,需用到下面两个属性:
stroke-dasharray =“number [, number , ….]”: 将虚线类型应用在描边上。
该值必须是用逗号分割的数字组成的数列,空格会被忽略。比如 3,5 :
第一个表示填色区域的长度为 3
第二个表示非填色区域的长度为 5
stroke-dashoffset:指定在 dasharray 模式下路径的偏移量。
- 值为 number 类型,除了可以正值,也可以取负值。
描边动画实现步骤:
1.先将描边设置为虚线
2.接着将描边偏移到不可见处
3.通过动画让描边慢慢变为可见,这样就产生了动画效果了。
路径-描边案例
雪糕路径描边动画案例实现步骤:
1.找到一个雪糕的 SVG 图片(设计师提供 | 网站下载)
2.将雪糕的每一个路径都改成虚线
3.将每个路径的描边都移动到虚线的空白处(不可见)
4.给每个路径添加动画,将路径描边慢慢移动到虚线填充处,即可。
什么是 SMIL?
SMIL(Synchronized Multimedia Integration Language 同步多媒体集成语言)是 W3C 推荐的可扩展标记语言,用于描述
多媒体演示。
SMIL 标记是用 XML 编写的,与 HTML 有相似之处。
SMIL 允许开发多媒体项目,例如:文本、图像、视频、音频等。
SMIL 定义了时间、布局、动画、视觉转换和媒体嵌入等标记,比如:
<head>
<body>
<seq>
<par>
<excl>
等元素
SMIL 的应用
目前最常用的 Web 浏览器基本都支持 SMIL 语言。
SVG 动画元素是基于 SMIL 实现(SVG 中使用 SMIL 实现元素有:
<set>
、<animate>
、<animateMotion>
...)。Adobe Media Player implement SMIL playback。
QuickTime Player implement SMIL playback。
SVG 动画实现方式
SVG 是一种基于 XML 的开放标准矢量图形格式,动画可以通过多种方式实现:
**1.用 JS 脚本实现:**可以直接通过 JavaScript 在来给 SVG 创建动画和开发交互式的用户界面。
**2.用 CSS 样式实现:**自 2008 年以来,CSS 动画已成为 WebKit 中的一项功能,使得我们可以通过 CSS 动画的方式来给文档对象
模型(DOM) 中的 SVG 文件编写动态效果。
- 3.用 SMIL 实现:一种基于 SMIL 语言实现的 SVG 动画。
SMIL 动画的优势
SVG 用 SMIL 方式实现动画,SMIL 允许你做下面这些事情:
变动一个元素的数字属性(x、y……)
变动变形属性(translation 或 rotation)
变动颜色属性
物件方向与运动路径方向同步等等
SMIL 方式实现动画的优势:
只需在页面放几个 animate 元素就可以实现强大的动画效果,无需任何 CSS 和 JS 代码。
SMIL 支持声明式动画。声明式动画不需指定如何做某事的细节,而是指定最终结果应该是什么,将实现细节留给客户端软件
在 JavaScript 中,动画通常使用 setTimeout() 或 setInterval() 等方法创建,这些方法需要手动管理动画的时间。而 SMIL声明式动画可以让浏览器自动处理,比如:动画轨迹直接与动画对象相关联、物体和运动路径方向、管理动画时间等等。
SMIL 动画还有一个令人愉快的特点是,动画与对象本身是紧密集成的,对于代码的编写和阅读性都非常好。
SMIL 动画的元素
SVG 中支持 SMIL 动画的元素:
<set>
<animate>
<animateColor>
<animateMotion>
更多:https://www.w3.org/TR/SVG11/animate.html#AnimationElements
Set 元素
<set>
元素提供了一种简单的方法,可以在指定的时间内设置属性的值。
set 元素是最简单的 SVG 动画元素。它是在经过特定时间间隔后,将属性设置为某个值(不是过度动画效果)。因此,图像不是连续动画,而是改变一次属性值。
它支持所有属性类型,包括那些无法合理插值的属性类型,例如:字符串 和 布尔值。而对于可以合理插值的属性通常首选
<animate>
元素。
<set>
元素常用属性:
- attributeName:指示将在动画期间更改的目标元素的 CSS 属性( property )或属性( attribute )的名称。
p attributeType: (已过期,不推荐)指定定义目标属性的类型(值为:CSS | XML | auto)。
to : 定义在特定时间设置目标属性的值。该值必须与目标属性的要求相匹配。 值类型:
<anything>
;默认值:无begin:定义何时开始动画或何时丢弃元素,默认是 0s ( begin 支持多种类型的值 )。
<set>
案例:
1)在 3 秒后自动将长方形瞬间移到右边
2)点击长方形后,长方形瞬间移到右边
Animate 元素
<animate>
元素给某个属性创建过度动画效果。需将 animate 元素嵌套在要应用动画的元素内。
<animate>
元素常用属性:
attributeName:指将在动画期间更改目标元素的 property (CSS 属)或 attribute 的名称。
动画值属性:
from:在动画期间将被修改的属性的初始值。没有默认值。
to :在动画期间将被修改的属性的最终值。没有默认值。
values:该属性具有不同的含义,具体取决于使用它的上下文(没有默认值) 。
它定义了在动画过度中使用的一系列值,值需要用分号隔开,比如:values=“2 ; 3; 4; 5”。
当 values 属性定义时,from、to 会被忽略。
动画时间属性:
begin:定义何时开始动画或何时丢弃元素。默认是 0s 。
dur:动画的持续时间,该值必须,并要求大于 0。单位可以用小时 ( h)、分钟 ( m)、秒 ( s) 或毫秒 ( ms) 表示。
fill:定义动画的最终状态。 freeze(保持最后一个动画帧的状态) | remove(保持第一个动画帧的状态)
repeatCount:指示动画将发生的次数:number| indefinite。没有默认值。
animateTransform 元素
<animateTransform>
元素
指定目标元素的形变(transform)属性,从而允许控制元素的平移、旋转、缩放或倾斜动画(类似于 CSS3 的形变)。
在一个动画元素中,只能用一个
<animateTransform>
元素创建动画;存在多个时,后面会覆盖前面的动画。
<animateTransform>
元素常用属性:
attributeName:指示将在动画期间更改的目标元素的 CSS 属性( property )或属性( attribute )的名称。
type :一个指定类型的属性,在不同的使用场景下,有不同的意思:
在
<animateTransform>
元素,只支持 translate(x, y) | rotate(deg, cx, cy) | scale(x, y) | skewX(x) | skewY(y) 。在 HTML 中的
<style>
和<script>
元素,它定义了元素内容的类型。
动画值属性:from、to 、values
动画时间属性:begin、dur、fill、repeatCount
animateMotion 元素
<animateMotion>
定义了一个元素如何沿着运动路径进行移动。
动画元素的坐标原点,会影响元素运动路径,建议从(0, 0)开始。
要复用现有路径,可在
<animateMotion>
元素中使用<mpath>
元素。
<aniamteMotion>
元素常用属性:
path:定义运动的路径,值和
<path>
元素的 d 属性一样,也可用 href 引用 一个<path>
。rotate :动画元素自动跟随路径旋转,使元素动画方向和路径方向相同,值类型:数字 | auto | auto-reverse; 默认值:0
动画值属性: from、to 、values
动画时间属性: begin、dur、fill、repeatCount
SVG + SMIL 动画
案例 1:飞机沿轨迹飞行动画
案例 2:加载进度动画
SVG + CSS3 动画
SVG + CSS3 动画
Snap.svg
什么是 Snap.svg?
Snap.svg 是一个专门用于处理 SVG 的 JavaScript 库 ( 类似 jQuery )。
Snap 为 Web 开发人员提供了干净、直观、功能强大的 API,这些 API 专门用来操作 SVG。
Snap 可用于创建动画,操作现有的 SVG 内容,以及生成 SVG 内容。
为什么选择 Snap.svg?
Snap 是由 DmitryBaranovskiy从零开始编写,专为现代浏览器(IE9 及更高版本、Safari、Chrome、Firefox 和 Opera)而设计。并且 Snap 可以支持遮罩、剪辑、图案、全渐变、组等功能。
Snap 还有一个独特功能是能够与现有的 SVG 一起工作。意味着 SVG 内容不必使用 Snap 生成,就可使用 Snap 来处理它。
- 比如可以在 Illustrator 或 Sketch 等工具中创建 SVG 内容,然后使用 Snap 对其进行动画处理和操作。
Snap 还支持动画。提供了简单直观的与动画相关的 JavaScript API,Snap 可以帮助你的 SVG 内容更具交互性和吸引力
Snap.svg 库处理 SVG 就像 jQuery 处理 DOM 一样简单,并且 Snap 是 100% 免费和 100% 开源的。
Snap.svg 初体验
Snap.svg 绘制一个圆, 如右图所示:
Snap.svg 常用的 API:
Snap: 工厂函数,创建或获取 SVG
- Snap(w, h) 、Snap(selector)….
Paper: 纸张 | SVG 画布
- circle、rect、line、path、text….
Element:元素
- animate、attr、select、before、after…
mina:通常用到的一些动画时间函数。
- mina.linear、mina.easeIn、mina.easeOut….
Snap 更多的 API 文档: http://snapsvg.io/docs/
SVG + Snap 动画
SVG + Snap 动画
GSAP 动画库
什么是 GSAP
GSAP 全称是( GreenSock Animation Platform)GreenSock 动画平台。
GSAP 是一个强大的 JavaScript 动画库,可让开发人员轻松的制作各种复杂的动画。
GSAP 动画库的特点
与 Snap.svg 不一样,GSAP 无论是 HTML 元素、还是 SVG、或是 Vue、React 组件的动画,都可以满足你的需求。
GSAP 的还提供了一些插件,可以用最少的代码创建令人震惊的动画,比如:ScrollTrigger 插件和 MorphSVG 插件。
GSAP 的核心是一个高速的属性操纵器,随着时间的推移,它可以极高的准确性更新值。它比 jQuery 快 20 倍!
GSAP 使用起来非常灵活,在你想要动画的地方基本都可以使用,并且是零依赖。
GSAP 官网:https://greensock.com/
GSAP 初体验
GSAP 初体验:移动 SVG 中的一个矩形
引入 gsap.js 动画库(CDN,本地,npm)。
调用 gsap.to 方法来执行 tween(补间/过度)动画。
GSAP 补间动画(Tween)
GSAP 的 Tween 动画有 4 中类型:
gsap.from(targets | selector, vars) - 元素从 from 定义的状态过度到元素当前的状态。
targets | selector : 需动画的元素对象,支持字符串的选择器
vars: 需过度动画的属性和 GSAP 扩展的 duration、ease、transformOrigin、repeat、delay、yoyo、stagger、onComplete 等
官网 gsap.form 文档:https://greensock.com/docs/v3/GSAP/gsap.from()
gsap.to(targets | selector, vars) - 元素从当前的状态过度到 to 状态。
gsap.fromTo(targets | selector, fromVars, toVars) -元素从 from 定义状态过度到 to 定义的状态
gsap.set(targets | selector, vars) - 立即设置属性(无过度效果)。
- 本质上是一个 duration = 0 的 to 补间动画。
哪些属性可以设置动画?
GSAP 几乎可以为任何属性制作动画
包括 CSS 属性、元素属性、自定义对象属性。
甚至 CSS 变量和复杂的字符串。
最常见的动画属性、变换和不透明度等。
GSAP 还专门给 CSS 形变(transform)相关属性提供了简写,如右图所示:
GSAP 动画时间线(TimeLine)
什么是动画时间线(TimeLine):
时间线(TimeLine)是用来创建易于调整、有弹性的动画序列。
当我们将补间添加到时间线(Timeline)时,默认情况下,它们会按照添加到时间轴的顺序一个接一个地播放。
TimeLine 的使用步骤:
第一步:通过 gsap.timeline( vars ) 拿到时间线对象
- timeline 文档: https://greensock.com/docs/v3/GSAP/Timeline
第二步:调用时间线上的 Tween 动画方法,比如:form、to 等。
SVG + GSAP 动画
SVG+GSAP 动画